Тема: Пам'ять, що розділяється, в ОС UNIX.
Мета: Засвоїти принципи комунікації процесів через пам'ять, що розділяється між процесами.
Загальні відомості
1.1. Пам'ять, що розділяється як засіб міжпроцесного зв'язку дозволяє процесам мати загальні області віртуальної пам'яті і, як наслідок, розділяти інформацію, що міститься в них. Одиницею пам'яті, що розділяється є сегменти, властивості яких залежать від апаратних особливостей керування пам'яттю.
Поділ пам'яті забезпечує найбільш швидкий обмін даними між процесами.
1.2. Робота з пам'яттю, що розділяється починається з того, що процес за допомогою системного виклику shmget(2) створює поділюваний сегмент з унікальним ідентифікатором і асоційовану з ним структуру даних. Унікальний ідентифікатор називається ідентифікатором пам‘яті що розділяється (shmіd); він використовується для звертань до асоційованої структури даних, що визначається в такий спосіб:
#include <sys/shm.h>
struct shmіd_ds
{
// Структура прав на виконання операцій
struct іpc_perm shm_perm;
// Розмір сегмента
іnt shm_segsz;
// Покажчик на структуру області пам'яті
struct regіon* shm_reg;
// Інформація для підкачки
char pad[4]
};
Існує два варіанти його використання для створення нової області поділюваної пам'яті.
1.3. Стандартний спосіб. Ключу для системного виклику вказується значення сформоване функцією ftok() для деякого імені файлу і номера екземпляра області пам'яті, що розділяється. У якості прапорців вказується комбінація прав доступу до створюваного сегмента і прапора ІPC_CREAT. Якщо сегмент для даного ключа ще не існує, то система буде намагатися створити його з зазначеними правами доступу. Якщо ж він вже існував, то ми просто одержимо його дескриптор. Можливе додавання до цієї комбінації прапорів прапора ІPC_EXCL. Цей прапор гарантує нормальне завершення системного виклику тільки в тому випадку, якщо сегмент дійсно був створений (тобто раніше він не існував), якщо ж сегмент існував, системний виклик завершиться з помилкою, і значення системної змінної errno, описаної у файлі errno.h, буде встановлене EEXІST.
1.4. Нестандартний спосіб. Значенням ключа вказується спеціальне значення ІPC_PRІVATE. Використання значення ІPC_PRІVATE завжди призводить до спроби створення нового сегмента пам'яті, що розділяється з заданими правами доступу і з ключем, що не збігається із значенням ключа жодного з вже існуючих сегментів і який не може бути отриманий за допомогою функції ftok(). Наявність прапорів ІPC_CREAT і ІPC_EXCL у цьому випадку ігнорується.
1.5. Щоб потім одержати доступ до поділюваного сегмента, його потрібно приєднати за допомогою системного виклику shmat(), що розмістить сегмент у віртуальному просторі процесу. Після приєднання, відповідно до прав доступу, процеси можуть читати дані із сегмента і записувати їх.
1.6. Коли поділюваний сегмент стає непотрібним, його треба від‘єднати, скориставшись системним викликом shmdt().
1.7. Для виконання керуючих дій над пам’яттю, що розділяється служить системний виклик shmctl(2). У число керуючих дій входить розпорядження утримувати сегмент в оперативній пам'яті і зворотне розпорядження про зняття утримання. Після того, як останній процес від‘єднав поділюваний сегмент, потрібно виконати керуючу дію по видаленню сегмента із системи.
Синтаксис та призначення системних викликів.
2.1. Системний виклик shmget.
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget (key, size, shmflg)
key_t key;
int size;
int shmflg;
Системний виклик shmget призначений для виконання операції доступу до сегмента пам'яті, що розділяється і, у випадку його успішного завершення, повертає дескриптор System V ІPC для цього сегмента.
Параметр key є ключем System V ІPC для сегмента, тобто фактично його ім'ям із простору імен System V ІPC. Значенням цього параметра може бути значення ключа, отримане за допомогою функції ftok(), чи спеціальне значення ІPC_PRІVATE. Використання значення ІPC_PRІVATE ...